package co.edu.udem.service.login;

import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.PostConstruct;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;

/**
 * handles the session ids.
 * 
 * @author sgranada
 * 
 */
@Controller("sessionManager")
public class SessionManager {

	/** a MAP with the usr|company|actor as a key and a session id as a value. */
	private ConcurrentHashMap<String, String> sessionMap;

	/** a MAP with the usr|company|actor as a key and a long value. */
	private ConcurrentHashMap<String, Long> expirationMap;

	/** the fixed period for the scheduler. */
	private static final long SCHEDULED_PERIOD = 300000;

	/** the session period. */
	private static final long SESSION_PERIOD = 3600000;

	/**
	 * checks if the user exist in session.
	 * 
	 * @param sessionId
	 *            session identifier.
	 * @return boolean true if the session is alive.
	 */
	public boolean isInSession(String sessionId) {
		return getSessionMap().containsValue(sessionId);
	}

	/**
	 * insert or updates the user session.
	 * 
	 * @param key
	 *            key of the user into session map.
	 * @return String user.
	 */
	public String insertOrUpdateUserSession(String key) {

		Session session = generateUUID();
		getSessionMap().put(key, session.getSessionId());
		getExpirationMap().put(key, session.getSessionDate());
		return session.getSessionId();
	}

	/**
	 * updates the expiration time for a session.
	 * @param key
	 *            key of the user into expired map.
	 */
	public void updateSessionExpiration(String key) {
		getExpirationMap().put(key, new Long(System.currentTimeMillis() + SESSION_PERIOD));
	}

	/**
	 * generates a unique UUID.
	 * 
	 * @return session identifier.
	 */
	public Session generateUUID() {
		return new Session(String.valueOf(UUID.randomUUID()), new Long(System.currentTimeMillis() + SESSION_PERIOD));
	}

	/**
	 * removes the expired sessions.
	 */
	@Scheduled(fixedRate = SCHEDULED_PERIOD)
	public void checkValidSessions() {

		long currentTime = System.currentTimeMillis();

		for (String key : getExpirationMap().keySet()) {

			if (currentTime > getExpirationMap().get(key)) {
				getSessionMap().remove(key);
				getExpirationMap().remove(key);
			}
		}

	}

	/**
	 * Method that setter information into maps.
	 */
	@PostConstruct
	public void setup() {
		sessionMap = new ConcurrentHashMap<String, String>();
		expirationMap = new ConcurrentHashMap<String, Long>();
	}

	/**
	 * @return the sessionMap
	 */
	public ConcurrentHashMap<String, String> getSessionMap() {
		return sessionMap;
	}

	/**
	 * @param sessionMap
	 *            the sessionMap to set
	 */
	public void setSessionMap(ConcurrentHashMap<String, String> sessionMap) {
		this.sessionMap = sessionMap;
	}

	/**
	 * @return the expirationMap
	 */
	public ConcurrentHashMap<String, Long> getExpirationMap() {
		return expirationMap;
	}

	/**
	 * @param expirationMap
	 *            the expirationMap to set
	 */
	public void setExpirationMap(ConcurrentHashMap<String, Long> expirationMap) {
		this.expirationMap = expirationMap;
	}

}
